﻿using CKS.Core.Framework;
using CKS.PLC.Core.Cache;
using FreeSql;
using FreeSql.DataAnnotations;
using FreeSql.Internal.Model;
using JinianNet.JNTemplate;
using Microsoft.IdentityModel.Tokens;
using System;
using System.Collections.Generic;
using System.Data.Common;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ZR.Model.Models.ProductionControl;
using static FreeSql.Internal.GlobalFilter;

namespace CKS.PLC.Action.System
{
    /// <summary>
    /// 
    /// 作用类型是加工结果，保存数据到1张表里
    /// </summary>
    public class SaveProcessingResults : PLCAction
    {
        public SaveProcessingResults(DecodeValue _value) : base(_value)
        {
        }


        public virtual AfterSaveResult AfterSaved(SaveArg e)
        {
            return new AfterSaveResult();
        }


        public virtual void BeforeReset()
        {

        }

        public object UpdateDynamicTableData(TableInfo fsqlTable, Dictionary<string, object> dict)
        {
            object obj = fsqlTable.CreateInstance(dict);
            conn.Update<object>().AsType(fsqlTable.Type)
                                .SetSource(obj).UpdateColumns(a => dict.Keys.ToArray()).ExecuteAffrows();
            return obj;
        }



        public override void Execute()
        {
            /*
                通用追溯
                根据点位关联的 PlcId\ActionId 查询到动作关联的表
             */

            var P = Value.Position;
            var act = conn.Select<CksPlcActions>().Where(a => a.ActionType == 1 && a.PlcId == P.PlcId && a.ActionId == P.ActionId && a.ActionKey == P.ActionKey  )
                .First();
            var table = conn.Select<CksVirtualTable>().Where(a => a.Id == act.BusinessId).First();
            var columns = conn.Select<CksVirtualColumn>().Where(a => a.TableId == act.BusinessId).OrderBy(a => a.Sequence).ToList();
            
            var replyPos = Value.GetReplyPosition(act.WriteDB, act.ActionId,act.ActionKey);
            var result = Value.Value.ToInt();
            if (result == 10)
            {
                string triggerNo = $"{Guid.NewGuid().ToString("N")}"; // 触发编号
                //获取分组情况

                var maxLocation = Value.GetMaxLocation();
                var sro = new AfterSaveResult();
                var fsqlTable = ServiceCommon.GetFreesqlTableInfo(table, columns);
                var arg = new SaveArg() {  
                    TableInfo = fsqlTable ,
                    VTable = table,
                    Columns = columns,
                    CksAction = act
                };
                if (maxLocation == 0)
                {
                    CksCollected cl = SaveDataRecord(arg, 0);
                    sro = AfterSaved(arg);//
                }
                else
                {
                    for (int i = 1; i <= maxLocation; i++)
                    {
                        CksCollected cl = SaveDataRecord(arg, i);
                        sro= AfterSaved(arg);//
                    }
                }

                


                //回复保存完成信号
                if(sro.CanExecute)
                    WriteInt16(replyPos, 20); //默认回复20已处理完成
                //EventBus.AddLog($"模块：数据采集；工站：{SiemensClient.PlcInfo.WorkstationCode};保存-{cl.SequenceId}-{cl.PrimaryCode}");
            }
            else if (result == 0)
            {
                //复位上位机的信号
                BeforeReset();
                WriteInt16(replyPos, 0);
               // EventBus.AddLog($"{table.Notes}；信号：{replyPos.Address};重置");
            }


        }

        private CksCollected SaveDataRecord(SaveArg e , int location)
        {
            string batchNo = $"{Guid.NewGuid().ToString("N")}"; // 数据批次
            e.VTable.MaxSeqId = GetNextSeq(e.VTable); //获取当前表格的最大虚拟Id
            List<CksCollectedDetails> details = new List<CksCollectedDetails>();
            CksCollected cl = new CksCollected()
            {
                BatchCode = batchNo,
                BatchSuffix = GetSuffix(batchNo, 5),
                CreatedTime = DateTime.Now,
                PlcId = e.CksAction.PlcId,
                SequenceId = e.VTable.MaxSeqId,
                TableId = e.VTable.Id,
                LocationId = location,
            };


            //遍历采集项
           
            var dict = new Dictionary<string, object>();
            string mainCode = string.Empty;
            foreach (var item in e.Columns)
            {
                string content = "";
                if(item.DataId>0)
                {
                    var decodeObject = Value.GetLinkDecodeData(location, item.DataId);
                    content = decodeObject.IsCharArray ? decodeObject.CharString : decodeObject.Value.ToString();
                }
                dict[item.ColumnName] = content;
                var model = new CksCollectedDetails()
                {
                    Content = content,
                    ColumnName = item.ColumnName,
                    ColumnId = item.Id,
                    PlcId = e.CksAction.PlcId,
                    TableId = e.VTable.Id,
                    BatchSuffix = GetSuffix(batchNo, 5),
                    BatchCode = batchNo,
                    CreatedTime = cl.CreatedTime
                };
                if(item.DataId>0)
                {
                    if (item.IsPrimary)
                    {
                        cl.PrimaryCode = content;
                        mainCode = content;
                        cl.Suffix_4 = GetSuffix(content);
                    }
                    if (item.IsResult)
                        cl.Result = content.ToInt();
                }
                details.Add(model);
            }

            dict["CreatedTime"] = DateTime.Now;
            dict["Nullity"] = false;
            dict["IsDeleted"] = false;
            dict["CheckResult"] = "0";
            object obj = e.TableInfo.CreateInstance(dict);
            e.InsertIdentityId = cl.IdentityId = conn.Insert<object>().AsType(e.TableInfo.Type).AppendData(obj).ExecuteIdentity(); //保存到动态表
            dict["Id"] = e.InsertIdentityId;
            e.RowData = dict;
           

            conn.Insert(details).ExecuteAffrows();
            conn.Insert(cl).ExecuteAffrows();
            conn.Update<CksVirtualTable>().SetSource(e.VTable)
                .UpdateColumns(a => a.MaxSeqId).ExecuteAffrows();

            
            return cl;
        }


        /*
         工具调用api更新表结构。
         从缓存获取表结构。
         通过字典方式写入表数据
         分页数据端直接查询动态类型，数据导出，
         查询条件也支持动态查询。


        
         
         */



        








        /// <summary>
        /// 内置序列
        /// </summary>
        /// <param name="table"></param>
        /// <returns></returns>
        private long GetNextSeq(CksVirtualTable table)
        {
            var n = conn.Select<CksVirtualTable>().Where(a => a.TableName == table.TableName).First();
            return n.MaxSeqId + 1;
        }

       

    }

    public class SaveArg
    {
        public TableInfo TableInfo { get; set; }

        public Dictionary<string,object> RowData { get; set; }
        public CksVirtualTable VTable { get;  set; }
        public List<CksVirtualColumn> Columns { get;  set; }
        public CksPlcActions CksAction { get;  set; }
        public long InsertIdentityId { get;  set; }
    }


    public class AfterSaveResult
    {
        /// <summary>
        /// 是否继续执行
        /// </summary>
        public bool CanExecute { get; set; } = true;
    }

}
